﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Moq;
using Ninject;
using SportsStore.Domain;
using SportsStore.Domain.Abstract;
using SportsStore.Domain.Concrete;
using SportsStore.Domain.Entities;
using SportsStore.WebUI.Infrastructure.Abstract;
using SportsStore.WebUI.Infrastructure.Concrete;

namespace SportsStore.WebUI.Infrastructure
{
    /// <summary>
    /// This is the controller factory that will resolve dependencies in each controller.
    /// This class is registered with the Asp.NET MVC framework in Global.asax file.
    /// </summary>
    public class NinjectControllerFactory : DefaultControllerFactory
    {
        private readonly IKernel _kernel;

        public NinjectControllerFactory()
        {
            _kernel = new StandardKernel();
            AddBindings();
        }

        /// <summary>
        /// The <see cref="DefaultControllerFactory"/> is used to create controllers.
        /// Once this controller is registered in the Global.asax file then this factory method will
        /// be called to create a controller by the Asp.NET MVC framework. The Ninject DI container
        /// will behave as a factory and resolve the dependency.
        /// </summary>
        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            IController controller = null;

            if (controllerType != null)
            {
                controller = (IController)_kernel.Get(controllerType);
            }

            return controller;
        }

        private void AddBindings()
        {
            _kernel.Bind<IProductRepository>().To<EFProductRepository>();
            _kernel.Bind<IOrderProcessor>().To<EmailOrderProcessor>();
            _kernel.Bind<IAuthProvider>().To<FormsAuthProvider>();

            //var mockRepository = new Mock<IProductRepository>();
            //mockRepository.Setup(repo => repo.Products).Returns(new List<Product>()
            //    {
            //        new Product() { Name = "Football", Price = 25 },
            //        new Product() { Name = "Surf board", Price = 179 },
            //        new Product() { Name = "Running shoes", Price = 95 }
            //    }.AsQueryable());

            // ToConstant binds the output value to the IProductRepository.
            // Bind<>().To<>() is used to bind to a type not a value. 
            // _kernel.Bind<IProductRepository>().ToConstant(mockRepository.Object);

        }
    }
}